#include<iostream>
using namespace std;

//class Point
//{
//public:
//	//默认构造
//	Point()
//	{
//		cout << "调用了构造函数" << endl;
//	}
//	//拷贝构造
//	Point(Point& p)
//	{
//		cout << "调用了拷贝构造函数" << endl;
//	}
//	//operator=()
//	Point& operator=(Point& p)
//	{
//		cout << "调用了operator=()" << endl;
//		return *this;
//	}
//	//析构函数
//	~Point()
//	{
//		cout << "调用了析构函数" << endl;
//	}
//public:
//	int _x;
//};
//
//void test()
//{
//	Point p;//默认构造
//	Point p1 = p;//拷贝构造
//	Point p2(p);//拷贝构造
//	p = p1;//operator=()
//}
//
//int main()
//{
//	test();
//	system("pause");
//	return 0;
//}

////请设计一个类，只能在堆上创建对象
////实现方式：
////1. 将类的构造函数私有，提供一个静态的成员函数，在该静态成员函数中完成堆对象的创建
////2. 拷贝构造直接delete掉。防止别人调用拷贝在栈上生成对象。
//
//class HeapOnly
//{
//public:
//	static HeapOnly* CreateObj()//提供一个成员函数，完成堆对象的创建，且该成员函数还必须是静态的
//	{                           //因为非静态成员函数必须用对象来调用，而创建对象必须调用CreateObj来创建
//		return new HeapOnly;    //静态成员函数才支持通过类调用：HeapOnly* ptr1 = HeapOnly::CreateObj();
//	}
//
//	HeapOnly(const HeapOnly& ho) = delete;//拷贝构造直接delete掉，因为拷贝构造出的对象是在栈上的
//
//	HeapOnly& operator=(HeapOnly& he)
//	{
//		cout << "HeapOnly& operator=(HeapOnly& he)" << endl;
//		return he;
//	}
//	
//private:
//	HeapOnly()//构造函数能设置为私有但不能直接delete，因为之后CreateObj还要用它创建对象
//		:_a(0)
//	{}
//private:
//	int _a;
//};
//
//int main()
//{
//	HeapOnly* hs1 = HeapOnly::CreateObj();
//	HeapOnly* hs2 = HeapOnly::CreateObj();
//	//赋值操作符重载不用delete掉
//	//eg:
//	hs1 = hs2;//--->注意，hs1、hs2都是指针这并不是HeapOnly的赋值操作符重载
//	          //    即使是HeapOnly赋值 也是堆上的对象给堆上的对象赋值
//	HeapOnly* hs3 = hs1;//注意，hs3是指针变量,不是对象。此处调用的不是构造函数，只是指针的赋值
//	HeapOnly* hs4;   
//	HeapOnly hs5;       //这个才创建新对象，调用构造函数
//	return 0;
//}

////请设计一个类，只能在栈上创建对象
////同理如上
//class StackOnly
//{
//public:
//	static StackOnly CreateObj()
//	{
//		return StackOnly();
//	}
//	//不用封拷贝构造，因为拷贝构造出来的就是在栈上的
//
//	// 禁掉StackOnly的operator new可以把下面用new调用拷贝构造申请对象给禁掉
//	// StackOnly obj = StackOnly::CreateObj();
//	// StackOnly* ptr3 = new StackOnly(obj);//此处的new调的是拷贝构造
//	void* operator new(size_t size) = delete;
//	void operator delete(void* p) = delete;
//private:
//	StackOnly()
//		:_a(0)
//	{}
//private:
//	int _a;
//};
//
//int main()
//{
//	//StackOnly* ptr1 = new StackOnly; //new调用构造
//	//StackOnly* ptr2 = new StackOnly(obj); //new调用拷贝构造
//	StackOnly obj1 = StackOnly::CreateObj();
//	StackOnly obj2 = StackOnly::CreateObj();
//	//赋值操作符重载不用delete掉。eg:
//	obj1 = obj2; //是栈上的对象给栈上的对象赋值
//
//	//用类对象构造，调的是拷贝构造，相当于StackOnly obj3(obj1);
//	StackOnly obj3 = obj1;
//	StackOnly obj4;//error，调的是构造函数
//
//	return 0;
//}

////请设计一个类，不能被继承
////附：
////C++有规定：子类要初始化父类的部分必须调用父类的构造函数，要清理父类的部分必须调用父类的析构函数。
////           拷贝和赋值时，父类的部分也是要调用父类的拷贝和赋值
////父类的private成员在子类是不可见的
//
////C++98方式
////父类的构造函数私有化，子类中调不到父类的构造函数。则无法继承。eg:
//class NonInherit
//{
//public:
//	static NonInherit GetInstance()
//	{
//		return NonInherit();
//	}
//private:
//	NonInherit()
//	{}
//};
//
////C++11方式
////final关键字，final修饰类，表示该类不能被继承。
//class A final 
//{
//	// ....
//};













